package muilt;

import java.io.IOException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;

import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

@Slf4j
public class OkHttp{
	
	private static final MediaType ME_JSON = MediaType.parse("application/json; charset=utf-8");
	private static OkHttpClient client = new OkHttpClient.Builder()
			.connectTimeout(10, TimeUnit.DAYS)
			.writeTimeout(10, TimeUnit.DAYS)
			.readTimeout(10, TimeUnit.DAYS)
			.build(); 
	List<String> cookies;
	private boolean noLogin = true;
	private String userName = "admin";
	private String passWord = "654321";
	private int tryLoginTimes = 10;
	private long lastBeatTime = 0; 
    //固定执行时间，时间单位为毫秒,读者可自行设定，不得小于等于0
    private static Integer cacheTime = 600000; //10分钟
    //开始后延迟时间，时间单位为毫秒,读者可自行设定，不得小于等于0
    private static Integer delay = 1000;
    
    private String host = "http://localhost/";
	private String loingUrl = host +"api/Admin/Login";
	private String buildingUrl = host + "api/Building/GetBuildingInfo?&moiid=%s";
	private String buildingRy = host + "api/Building/GetBuildingRy?&moiId=%s";
	private String getAll = host + "api/Building/GetAll?&minX=%s&minY=%s&maxX=%s&maxY=%s";
	private String refreshUrl = buildingUrl + "1165";
	
	@Test
	public void test(){
		System.out.println(GetBuildingInfo("1165"));
		System.out.println(GetBuildingRy("1165"));
		System.out.println(GetAll("13722830.382734943","4070785.3280186914","13723429.245649494","4071290.524180713"));
	}
	
	public String GetAll(String minX,String minY,String maxX,String maxY){
		if(noLogin){
			relogin(tryLoginTimes);
		} 
		try {
		    Response response = client.newCall(new Request.Builder().header("Cookie", Joiner.on(",").skipNulls().join(cookies)).url(String.format(getAll, minX,minY,maxX,maxY)).build()).execute(); 
		    if(response.isSuccessful()){
		    	return response.body().string();
		    }else{
		    	return "FAIL";
		    } 
		} catch (Exception e) {
			e.printStackTrace();
			log.debug("GetBuildingInfo fail");
			return "FAIL";
		} finally{
			resfreshBeaTime();
		}
	} 
	
	public String GetBuildingInfo(String moiid){
		if(noLogin){
			relogin(tryLoginTimes);
		} 
		try {
		    Response response = client.newCall(new Request.Builder().header("Cookie", Joiner.on(",").skipNulls().join(cookies)).url(String.format(buildingUrl,moiid)).build()).execute(); 
		    if(response.isSuccessful()){
		    	return response.body().string();
		    }else{
		    	return "FAIL";
		    } 
		} catch (Exception e) {
			e.printStackTrace();
			log.debug("GetBuildingInfo fail");
			return "FAIL";
		} finally{
			resfreshBeaTime();
		}
	} 

	public String GetBuildingRy(String moiid){
		if(noLogin){
			relogin(tryLoginTimes);
		} 
		try {
		    Response response = client.newCall(new Request.Builder().header("Cookie", Joiner.on(",").skipNulls().join(cookies)).url(String.format(buildingRy,moiid)).build()).execute(); 
		    if(response.isSuccessful()){
		    	return response.body().string();
		    }else{
		    	return "FAIL";
		    } 
		} catch (Exception e) {
			e.printStackTrace();
			log.debug("GetBuildingInfo fail");
			return "FAIL";
		} finally{
			resfreshBeaTime();
		}
	}
	
    private void heartBeat(){
    	 Timer timer = new Timer();
         timer.schedule(new TimerTask() {
        	 @Override
        	 public void run(){
        		 refreshSession();
           	 }
         }, delay, cacheTime);
    } 
	
    /**
     * 刷新服务器的session时间
     */
    private void refreshSession(){
    	try { 
    		if(System.currentTimeMillis() - lastBeatTime < cacheTime){
    			return;
    		}
    		if(noLogin){
    			relogin(tryLoginTimes);
    		}
    		if(!noLogin){ 
                client.newCall(new Request.Builder()
                		.header("Cookie", Joiner.on(",")
                		.skipNulls().join(cookies))
                		.url(refreshUrl).build()).execute(); 	
    		}
    		resfreshBeaTime();
		} catch (Exception e) {
			e.printStackTrace();
			log.debug("session heart beat is exception");
		}
    } 
    /**
     * 刷新心跳时间
     */
    private void resfreshBeaTime(){
    	lastBeatTime = System.currentTimeMillis();
    }
	/**
	 * 如果登录失败进行 重复登录count次
	 */
	private boolean relogin(int count){
		try {
			count--;
			if(doLoing()){
				return true;
			}else if(count >= 0){
				Thread.sleep(1000);
	            return relogin(count);
			}else{
				return false;
			}	
		} catch (Exception e) {
			log.debug("try to login is exception");
			return false; 
		} 
    }
	/**
	 * 真实的登录方法 
	 */
	private boolean doLoing() throws IOException{ 
		Response response = client.newCall(new Request.Builder()
				.url(loingUrl).post(RequestBody
				.create(ME_JSON,JSON.toJSON(ImmutableMap
				.of("userName", userName, "userPassword", passWord)).toString()))
				.build()).execute(); 
		if(response != null && response.isSuccessful()){
			noLogin = false;
			cookies = response.headers().values("Set-Cookie");
			return true;
		}else{
			return false;
		}
	} 
} 